package net.qiqbframework.mp;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.qiqbframework.common.utils.CollectionUtil;
import net.qiqbframework.common.utils.StringUtil;
import net.qiqbframework.config.Configuration;
import net.qiqbframework.persisthanding.dao.BasicEntityPo;
import net.qiqbframework.persisthanding.dao.BasicEntityPoDao;
import org.javers.core.Javers;
import org.javers.core.diff.Diff;
import org.javers.core.metamodel.clazz.EntityDefinition;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.util.*;

@Slf4j
public class BasicEntityPoDaoMpImpl<M extends BaseMapper<Po>, Po extends BasicEntityPo> extends ServiceImpl<M, Po> implements BasicEntityPoDao<Po>
        , SmartInitializingSingleton {

    private String DEFAULT_ENTITY_ID = "id";


    @Autowired
    private Configuration configuration;


    public BasicEntityPoDaoMpImpl() {
        // 扫描ID

    }

    @Override
    public List<Po> batchSelectPosByIds(Collection<String> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return super.listByIds(ids);
    }

    @Override
    public Po selectPoById(String id) {
        if (StringUtil.isEmpty(id)) {
            return null;
        }
        return super.getById(id);
    }

    @Override
    public boolean dynamicUpdateById(Po newPO, Po oldPO) {
        if (newPO == null) {
            throw new IllegalStateException("准备更新的对象不能为空");
        }
        if (oldPO == null) {
            throw new IllegalStateException("对比的对象不能为空");
        }
        final Javers poJavers = configuration.poJavers();
        if (poJavers.getTypeMapping(getEntityClass()) == null) {
            log.warn("dynamicUpdateById 类型[{}]暂时没有注册比较信息，为了防止比较异常，默认为变更", getEntityClass());
            return super.updateById(newPO);
        } else {
            final Diff compare = poJavers.compare(oldPO, newPO);
            if (compare.hasChanges()) {
                return super.updateById(newPO);
            } else {
                log.info(" 没有变更字段，无需更新，新值:{},旧值:{}", newPO, oldPO);
            }
        }

        return true;
    }

    @Override
    public boolean batchDynamicUpdateById(Map<Po, Po> newAndOldMap) {
        List<Po> preUpdate = new ArrayList<>();
        for (Map.Entry<Po, Po> entry : newAndOldMap.entrySet()) {
            final Javers poJavers = configuration.poJavers();
            final Diff compare = poJavers.compare(entry.getValue(), entry.getKey());
            if (compare.hasChanges()) {
                preUpdate.add(entry.getKey());
            }

        }

        return super.updateBatchById(preUpdate);
    }

    @Override
    public boolean batchInsertPos(Collection<Po> pos) {
        if (CollectionUtil.isEmpty(pos)) {
            return false;
        }
        return super.saveBatch(pos);
    }

    @Override
    public boolean batchDeletePosById(Collection<Po> pos) {
        if (CollectionUtil.isEmpty(pos)) {
            return false;
        }
        return super.removeByIds(pos);
    }

    @Override
    public void afterSingletonsInstantiated() {
        configuration.poJaversBuilder().registerEntity(new EntityDefinition(this.getEntityClass(), DEFAULT_ENTITY_ID));
    }
}
